home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / util / sys / CopyReplace.lha / Source / Copy.c next >
C/C++ Source or Header  |  1998-01-10  |  30KB  |  1,084 lines

  1. #define NAME         "Copy"
  2. #define REVISION     "13"
  3. #define DISTRIBUTION "(Freeware) "
  4. //#define DEBUG
  5.  
  6. /* Programmheader
  7.  
  8.         Name:           Copy
  9.         Author:         SDI
  10.         Distribution:   Freeware
  11.         Description:    copies, moves, deletes and links files
  12.         Compileropts:   -
  13.         Linkeropts:     -gsi -l amiga
  14.  
  15.  1.0   02.08.97 : first version, only raw source
  16.  1.1   06.08.97 : added more stuff
  17.  1.2   08.08.97 : completed option description, added new code
  18.  1.3   09.08.97 : and more stuff done and SILENT option
  19.  1.4   11.08.97 : fixed problem with DELETE and ExNext function
  20.  1.5   14.08.97 : fixed DoWork, added new stuff
  21.  1.6   17.08.97 : added more functions, program is near completion
  22.  1.7   24.08.97 : bug fixes in DoWork function
  23.  1.8   25.09.97 : included missing functions, started debugging
  24.  1.9   26.09.97 : debugging, source cleanup
  25.  1.10  28.09.97 : and still debugging
  26.  1.11  30.09.97 : fixed some errors
  27.  1.12  04.10.97 : Added FORCE Option
  28.  1.13  19.12.97 : added DIRECT option
  29. */
  30.  
  31. #include <proto/dos.h>
  32. #include <proto/exec.h>
  33. #include <exec/memory.h>
  34. #include "SDI_defines.h"
  35. #define SDI_TO_ANSI
  36. #include "SDI_ASM_STD_protos.h"
  37.  
  38. #define PARAM   "FROM/M,TO,PAT=PATTERN/K,BUF=BUFFER/K/N,ALL/S,"         \
  39.                 "DIRECT/S,CLONE/S,DATES/S,NOPRO/S,COM=COMMENT/S,"       \
  40.                 "QUIET/S,SILENT/S,NOREQ/S,ERRWARN/S,MAKEDIR/S,"         \
  41.                 "MOVE/S,DELETE/S,HARD=HARDLINK/S,SOFT=SOFTLINK/S,"      \
  42.                 "FOLNK=FORCELINK/S,FODEL=FORCEDELETE/S,"                \
  43.                 "FOOVR=FORCEOVERWRITE/S,DONTOVR=DONTOVERWRITE/S,"    \
  44.                 "FORCE/S"
  45.  
  46. #define COPYFLAG_ALL            (1<<0)
  47. #define COPYFLAG_DATES          (1<<1)
  48. #define COPYFLAG_NOPRO          (1<<2)
  49. #define COPYFLAG_COMMENT        (1<<3)
  50. #define COPYFLAG_FORCELINK      (1<<4)
  51. #define COPYFLAG_FORCEDELETE    (1<<5)
  52. #define COPYFLAG_FORCEOVERWRITE (1<<6)
  53. #define COPYFLAG_DONTOVERWRITE  (1<<7)
  54. #define COPYFLAG_QUIET          (1<<8)
  55. #define COPYFLAG_SILENT         (1<<9)
  56. #define COPYFLAG_ERRWARN    (1<<10)
  57.  
  58. #define COPYFLAG_SOFTLINK       (1<<20) /* produce softlinks */
  59. #define COPYFLAG_DEST_FILE      (1<<21) /* one file mode */
  60. #define COPYFLAG_DONE           (1<<22) /* did something in DoWork */
  61. #define COPYFLAG_ENTERSECOND    (1<<23) /* entered directory second time */
  62.  
  63. #define COPYMODE_COPY           0
  64. #define COPYMODE_MOVE           1
  65. #define COPYMODE_DELETE         2
  66. #define COPYMODE_MAKEDIR    3
  67. #define COPYMODE_LINK           4
  68.  
  69. #define PRINTOUT_SIZE           50      /* maximum size of name printout */
  70. #define PRINTOUT_SPACES         10      /* maximum number of spaces      */
  71.  
  72. #define FILEPATH_SIZE           300     /* maximum size of filepaths     */
  73.  
  74. /* return values */
  75. #define TESTDEST_DIR_OK         2       /* directory exists, go in */
  76. #define TESTDEST_DELETED        1       /* file or empty directory deleted */
  77. #define TESTDEST_NONE           0       /* nothing existed */
  78. #define TESTDEST_ERROR          -1      /* an error occured */
  79. #define TESTDEST_CANTDELETE     -2      /* deletion not allowed (DONTOV) */
  80.  
  81. struct Args {
  82.   STRPTR *      from;
  83.   STRPTR        to;
  84.   STRPTR        pattern;
  85.   LONG *        buffer;
  86.   LONG          all;
  87.   LONG        direct;
  88.   LONG          clone;
  89.   LONG          dates;
  90.   LONG          nopro;
  91.   LONG          comment;
  92.   LONG          quiet;
  93.   LONG          silent;
  94.   LONG          noreq;
  95.   LONG        errwarn;
  96.   LONG        makedir;
  97.   LONG          move_mode;
  98.   LONG          delete_mode;
  99.   LONG          hardlink;
  100.   LONG          softlink;
  101.   LONG          forcelink;
  102.   LONG          forcedelete;
  103.   LONG          forceoverwrite;
  104.   LONG          dontoverwrite;
  105.   LONG        force;
  106. };
  107.  
  108. struct CopyData {
  109.   ULONG         Flags;
  110.   ULONG         BufferSize;
  111.   STRPTR        Pattern;
  112.   ULONG         Destination;
  113.   ULONG         CurDest;  /* Current Destination */
  114.   ULONG        DestPathSize;
  115.   struct FileInfoBlock *Fib;
  116.   UBYTE         Mode;
  117.   UBYTE         RetVal;         /* when set, error output is already done */
  118.   UBYTE         RetVal2;        /* when set, error output must be done */
  119.   UBYTE         Deep;
  120.   UBYTE        FileName[FILEPATH_SIZE];
  121.   UBYTE        DestName[FILEPATH_SIZE];
  122. };
  123.  
  124. #define TEXT_READ        texts[0]
  125. #define TEXT_COPIED             texts[1]
  126. #define TEXT_MOVED              texts[2]
  127. #define TEXT_DELETED            texts[3]
  128. #define TEXT_LINKED             texts[4]
  129. #define TEXT_RENAMED            texts[5]
  130. #define TEXT_CREATED            texts[6]
  131. #define TEXT_ENTERED            texts[7]
  132. #define TEXT_OPENED_FOR_OUTPUT  texts[8]
  133. #define TEXTNUM_MODE            9
  134. #define TEXT_DIRECTORY          texts[15]
  135. #define TEXT_NOT_DONE           texts[16]
  136. #define TEXT_NOTHING_DONE       texts[17]
  137. #define TEXT_ERR_FORCELINK      texts[18]
  138. #define TEXT_ERR_DELETE_DEVICE  texts[19]
  139. #define TEXT_ERR_DEST_DIR       texts[20]
  140. #define TEXT_ERR_INFINITE_LOOP  texts[21]
  141. #define TEXT_ERR_WILDCARD_DEST  texts[22]
  142.  
  143. STRPTR texts[] =
  144. {
  145. "read",
  146. "copied",
  147. "moved",
  148. "deleted",
  149. "linked",
  150. "renamed",
  151. "created",
  152. "entered",
  153. "opened for output",
  154. "COPY mode\n",
  155. "MOVE mode\n",
  156. "DELETE mode\n",
  157. "MAKEDIR mode\n",
  158. "HARDLINK mode\n",
  159. "SOFTLINK mode\n",
  160. "%s <Dir>",                /* output of directories */
  161. "not %s: ",
  162. "No file was processed.\n",
  163. "FORCELINK keyword required.\n",
  164. "A device cannot be deleted.",
  165. "Destination must be a directory.\n",
  166. "Infinite loop not allowed.\n",
  167. "Wildcard destination invalid.\n",
  168. };
  169.  
  170. LONG  CopyFile(ULONG, ULONG, ULONG);
  171. void  DoWork(STRPTR, struct CopyData *);
  172. LONG  IsPattern(STRPTR); /* return 0 -> NOPATTERN, return -1 --> ERROR */
  173. LONG  KillFile(STRPTR, ULONG);
  174. LONG  LinkFile(ULONG, STRPTR, ULONG);
  175. ULONG OpenDestDir(STRPTR, struct CopyData *);
  176. void  PatCopy(STRPTR, struct CopyData *);
  177. void  PrintName(STRPTR, ULONG, ULONG, ULONG);
  178. void  PrintNotDone(STRPTR, STRPTR, ULONG, ULONG);
  179. void  SetData(STRPTR, struct CopyData *);
  180. LONG  TestDest(STRPTR, ULONG, struct CopyData *);
  181. ULONG TestLoop(ULONG, ULONG);
  182.  
  183. struct DosLibrary *DOSBase;
  184.  
  185. ULONG start(void)
  186. {
  187.   struct Process *task;
  188.   struct DosLibrary *dosbase;
  189.   struct CopyData cd = {0,102400,0,0,0,0,0,COPYMODE_COPY,0,RETURN_FAIL,1};
  190.  
  191.   /* test for WB and reply startup-message */
  192.   if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  193.   {
  194.     WaitPort(&task->pr_MsgPort);
  195.     Forbid();
  196.     ReplyMsg(GetMsg(&task->pr_MsgPort));
  197.     return RETURN_FAIL;
  198.   }
  199.   else if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  200.   {
  201.     STRPTR a[2] = {"", 0};
  202.     struct RDArgs *rda;
  203.     struct Args args = {0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0};
  204.  
  205.     DOSBase = dosbase;
  206.  
  207.     if((rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
  208.     {
  209.       rda->RDA_ExtHelp =
  210.       "FROM     multiple input files\n"
  211.       "TO       destination file or directory\n"
  212.       "PATTERN  a pattern the filenames must match\n"
  213.       "BUFFER   buffersize for copy buffer (default 200 [100K])\n"
  214.       "ALL      deep scan into sub directories\n"
  215.       "DIRECT   copy mode only: copy file without any tests or options\n"
  216.       "CLONE    copy comment, protection bits and date as well\n"
  217.       "DATES    copy dates\n"
  218.       "NOPRO    do not copy protection bits\n"
  219.       "COMMENT  copy filecomment\n"
  220.       "QUIET    suppress all output and requesters\n"
  221.       "SILENT   suppress output, but not errors and requesters\n"
  222.       "NOREQ    suppress requesters\n"
  223.       "ERRWARN  do not proceed, when one file failed\n"
  224.       "MAKEDIR  produce directories\n"
  225.       "MOVE     delete source files after copying successful\n"
  226.       "DELETE   do not copy, but delete the source files\n"
  227.       "HARDLINK make a hardlink to source instead of copying\n"
  228.       "SOFTLINK make a softlink to source instead of copying\n"
  229.       "FOLNK    also makes links to directories\n"
  230.       "FODEL    delete protected files also\n"
  231.       "FOOVR    also overwrite protected files\n"
  232.       "DONTOVR  do never overwrite destination\n"
  233.       "FORCE    DO NOT USE. Call compatibility only.\n";
  234.  
  235.       if(ReadArgs(PARAM, (LONG *) &args, rda))
  236.       {
  237.         ULONG patbufsize = 0;
  238.         LONG i = 0;
  239.         APTR win = task->pr_WindowPtr;
  240.  
  241.         if(args.quiet) /* when QUIET, SILENT and NOREQ are also true! */
  242.           args.silent = args.noreq = 1;
  243.  
  244.         if(